import json

from django.core.cache import cache

from apps.core.models import Product
from util.ApiResponse import traffic_control_response


class RateLimitMiddleware:

    def __init__(self, get_response):
        self.get_response = get_response
        self.max_requests = 500  # 每秒最大请求数（针对商品）
        self.window_seconds = 1  # 限流时间窗口（秒）
        self.product_threshold = 100  # 热门商品的访问阈值（访问超过此值标记为热门商品）

    def __call__(self, request):
        """
        每次请求进来时，检查是否超出商品的限流阈值，并统计热门商品访问。
        :param request: Django 请求对象
        :return: 如果限流，返回拒绝响应；否则继续请求处理
        """
        product_id = request.GET.get('product_id')
        if product_id:
            # 限流：检查该商品是否超出访问阈值
            product_key = f"product_{product_id}_access"

            # 获取当前商品的访问次数
            current_count = cache.get(product_key, 0)

            # 如果超过最大请求数，返回限流响应
            if current_count >= self.max_requests:
                return traffic_control_response

            # 更新商品的访问次数
            cache.set(product_key, current_count + 1, timeout=self.window_seconds)

            # 统计商品访问频率并标记热门商品
            self.track_product_access(product_id)

        # 正常请求处理
        response = self.get_response(request)
        return response

    def track_product_access(self, product_id):
        """
        统计商品的访问频率，判断是否为热门商品。
        :param product_id: 商品 ID
        """
        product_key = f"product_access_{product_id}"

        # 获取当前商品的访问次数
        current_count = cache.get(product_key, 0)

        # 更新商品的访问次数
        cache.set(product_key, current_count + 1, timeout=self.window_seconds)

        # 如果商品的访问次数超过阈值，标记为热门商品
        if current_count + 1 >= self.product_threshold:
            self.mark_as_hot(product_id)

    def mark_as_hot(self, product_id):
        """
        将商品标记为热门商品。
        :param product_id: 商品 ID
        """
        # 将商品标记为热门商品，用缓存表示热门商品
        Product.objects.filter(id=product_id).values()
        cache.set(f"hot_product_{product_id}", True, timeout=60 * 60 * 24)  # 热门商品标记持续 24 小时

    def cache_product_info(self,product_id):
        """
        将商品的完整信息存入缓存
        :param product_id: 商品 ID
        """
        product = Product.objects.filter(id=product_id).first()

        if product:
            # 获取商品的相关信息
            product_data = {
                "id": product.id,
                "name": product.name,
                "stock": product.stock,
                "price": product.price,
                "description": product.description,
            }

            # 将商品信息序列化为 JSON，并存入缓存，缓存持续 24 小时
            cache.set(f"product_{product_id}_info", json.dumps(product_data), timeout=60 * 60 * 24)

            return product_data
        return None